package com.nami.client.service.impl;

import cn.hutool.core.lang.UUID;
import com.nami.basic.enums.protocol.UpCMDEnum;
import com.nami.basic.packet.Packet;
import com.nami.basic.packet.message.Message;
import com.nami.basic.packet.message.MsgUser;
import com.nami.client.cache.ClientChannelCache;
import com.nami.client.network.NettyClient;
import com.nami.client.qos.QosReceiver;
import com.nami.client.request.LoginRequest;
import com.nami.client.request.ServerConfig;
import com.nami.client.request.message.Payload;
import com.nami.client.service.ClientService;
import com.nami.client.utils.ClientKeyUtil;
import com.nami.client.utils.JsonUtils;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;

import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j
public class ClientServiceImpl implements ClientService {

    private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);


    private ServerConfig config;

    private LoginRequest loginRequest;


    private Channel channel;

    public ClientServiceImpl(ServerConfig config, LoginRequest loginRequest) {
        this.config = config;
        this.loginRequest = loginRequest;
    }

    @Override
    public void start() throws Exception {

        NettyClient nettyClient = new NettyClient(config, loginRequest);
        channel = nettyClient.start();
        ClientChannelCache.add(ClientKeyUtil.genClientKey(loginRequest.getUserId(), loginRequest.getDeviceType()) , channel);
        logout();

        Thread.sleep(2000);

        login();
        Thread.sleep(20000);

        scheduler.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                try {
                    Packet packet = new Packet();
                    packet.setCmd(UpCMDEnum.PING.getCode());
                    packet.setBody(new byte[0]);
                    packet.setMagic((byte) 8);
                    packet.setSerial((byte) 0);
                    packet.setVersion((byte) 0);
                    packet.setEncrypt((byte) 0);
                    channel.writeAndFlush(packet);
                    log.info("[ping] userId={}", loginRequest.getUserId());
                } catch (Exception var3) {
                    var3.printStackTrace();
                    log.error("[client] 发送ping 失败。msg={}", var3.getMessage());
                }
            }
        }, 1, 19, TimeUnit.SECONDS);

        log.info("client init success.");

    }

    @Override
    public void send() {

        try {
//            int i = RandomUtil.randomInt();
//            if (i % 2 != 0) {
//                log.warn("暂不发群消息.");
//                return;
//            }

            Packet packet = new Packet();
            packet.setCmd(UpCMDEnum.C2G.getCode());

            Message message = new Message();
            message.setSenderId(loginRequest.getUserId());
            message.setReceiverId("12345678");
            Payload payload = new Payload();

            payload.setText(randomStr());
            message.setPayload(JsonUtils.toJsonString(payload));
            message.setPayloadType("text");
            message.setClientMsgId(UUID.fastUUID().toString());
            message.setCid("12345678");
            message.setConversationType("c2g");

//            MsgUser user = new MsgUser();
//            user.setNick();
//            user.setAvatar( );
//            message.setSenderInfo();

            packet.setBody(JsonUtils.toJsonByte(message));
            packet.setMagic((byte) 8);
            packet.setSerial((byte) 10);
            packet.setVersion((byte) 0);
            packet.setEncrypt((byte) 0);
            channel.writeAndFlush(packet);
//            log.info("[c2g] 发送消息, clientMsgId={} msg={}", message.getClientMsgId(), payload.getText());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String randomStr() {
        // 扩展字符集合，包含更多常用简单中文字符
        String chineseChars = "的一是在不了有和人这中大为上个国我以要他时来用们生到作地于出就分对成会可主发年动同工也能下过子说产种面而方后多定行学法所民得经十三之进样理心体信息东";
        // 添加更多字符
        chineseChars += "南北西春夏秋冬上下左右前后内外真假好坏美丑善恶强弱大小长短高低胖瘦黑白红黄绿蓝紫金银铜铁锡铅";
        StringBuilder sb = new StringBuilder();
        Random random = new Random();

        int length = random.nextInt(15) + 1; // 生成1到15之间的随机长度
        for (int i = 0; i < length; i++) {
            int index = random.nextInt(chineseChars.length());
            sb.append(chineseChars.charAt(index));
        }

        return sb.toString();
    }

    private void logout() {
        Packet packet = new Packet();
        packet.setCmd(UpCMDEnum.LOGOUT.getCode());
        packet.setMagic((byte) 8);
        packet.setSerial((byte) 1);
        packet.setVersion((byte) 1);
        packet.setSerial((byte) 10);
        packet.setBody(JsonUtils.toJsonByte(loginRequest));
        channel.writeAndFlush(packet);
        log.info("[client] 发送注销请求。userId={}", loginRequest.getUserId());
    }


    public void login() {
        Packet packet = new Packet();
        packet.setCmd(UpCMDEnum.LOGIN.getCode());
        packet.setMagic((byte) 8);
        packet.setSerial((byte) 1);
        packet.setVersion((byte) 1);
        packet.setSerial((byte) 10);
        loginRequest.setCurrTime(System.currentTimeMillis());
        packet.setBody(JsonUtils.toJsonByte(loginRequest));
        channel.writeAndFlush(packet);
        log.info("[client] 发送登录请求。userId={}", loginRequest.getUserId());
    }


}
